#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""  
@Project : project
@File : subdomain.py
@Author : 薄荷糖
@Time : 2025/9/9 19:30  
@脚本说明 : 
"""
import threading
import warnings
import socket
import requests

warnings.filterwarnings("ignore")

# 请求头，模拟浏览器
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36",
}

# DNS 探测：判断子域名是否有 IP（是否有 DNS 记录）
def has_dns_record(subdomain):
    try:
        # 尝试解析子域名的 A 记录（IPv4）
        socket.gethostbyname(subdomain)
        return True  # DNS 解析成功，说明存在
    except socket.gaierror:
        return False  # DNS 解析失败，子域名不存在

# HTTP 探测：判断子域名是否可以访问（返回 200/3xx 等）
def http_check(subdomain):
    urls = [
        f"http://{subdomain}",
        f"https://{subdomain}",
    ]
    for url in urls:
        try:
            r = requests.get(url, headers=headers, timeout=5)
            # 如果返回 200~399 之间的状态码，认为“存活”
            if 200 <= r.status_code < 400:
                print(f"[+] {subdomain} 存活 [HTTP {r.status_code}]")
                return True
        except:
            continue
    return False

# 单个子域名扫描任务（先 DNS，后 HTTP）
def subdomain_scan(domain, sub):
    full_subdomain = f"{sub}.{domain}"  # 拼接完整子域名，如 api.baidu.com
    if has_dns_record(full_subdomain):  # 第一步：DNS 是否存在
        if http_check(full_subdomain):   # 第二步：HTTP 是否可访问
            pass  # 已经在 http_check 中打印了结果
        else:
            # 可选：DNS 有但 HTTP 无响应，你也可以打印
            # print(f"[-] {full_subdomain} DNS存在但HTTP无响应")
            pass
    else:
        # 可选：DNS 都没有，直接跳过
        # print(f"[-] {full_subdomain} DNS不存在")
        pass

# 主函数：读取字典，多线程扫描
def run_subdomain(domain, dict_file):
    try:
        with open(dict_file, 'r', encoding='utf-8') as f:
            subs = [line.strip() for line in f if line.strip() and not line.startswith('#')]

        threads = []
        for sub in subs:
            t = threading.Thread(target=subdomain_scan, args=(domain, sub))
            t.start()
            threads.append(t)

        for t in threads:
            t.join()  # 等待所有线程完成
    except Exception as e:
        print(f"[-] 子域名扫描出错: {e}")

